package com.swak.wechat;

import java.util.concurrent.CompletableFuture;

import com.swak.codec.Encodes;
import com.swak.http.HttpService;
import com.swak.utils.StringUtils;
import com.swak.wechat.component.AuthorizationInfo;
import com.swak.wechat.component.AuthorizerAccessToken;
import com.swak.wechat.component.AuthorizerInfoResult;
import com.swak.wechat.component.AuthorizerOption;
import com.swak.wechat.component.ComponentAccessToken;
import com.swak.wechat.component.PreAuthCode;
import com.swak.wechat.component.StartPushTicketResult;
import com.swak.wechat.token.AccessToken;
import com.swak.wechat.user.SnsToken;

public abstract class AbstractComponentService {

	/**
	 * Http 服务
	 *
	 * @return http 服务
	 */
	public abstract HttpService getHttpService();

	/**
	 * 第三方平台：换取 accessToken
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<StartPushTicketResult> startPushTicket_component(ComponentConfig app) {
		CompletableFuture<StartPushTicketResult> future = this.getHttpService().post()
				.setUrl("https://api.weixin.qq.com/cgi-bin/component/api_start_push_ticket")
				.addFormParam("component_appid", app.getAppId()).addFormParam("component_appsecret", app.getSecret())
				.jsonResult(StartPushTicketResult.class).future();
		return future.thenApply(token -> {
			return token;
		});
	}

	/**
	 * 第三方平台：换取 accessToken
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<AccessToken> accessToken_component(ComponentConfig app) {
		CompletableFuture<AccessToken> future = this.getHttpService().get()
				.setUrl("https://api.weixin.qq.com/cgi-bin/component/api_component_token")
				.addQueryParam("component_appid", app.getAppId()).addQueryParam("component_appsecret", app.getSecret())
				.addQueryParam("component_verify_ticket", app.getVerifyTicket()).jsonResult(ComponentAccessToken.class)
				.future();
		return future.thenApply(token -> {
			if (token != null) {
				token.setAddTime(System.currentTimeMillis());
			}
			return token;
		});
	}

	/**
	 * 授权登录的地址
	 *
	 * @param app   app
	 * @param url   地址
	 * @param state state
	 * @return 异步结果
	 */
	public CompletableFuture<String> toAuthorize_component(AuthorizerWechatConfig app, String url, String state) {
		String content = com.swak.Constants.REDIRECT_URL_PREFIX + "https://open.weixin.qq.com/connect/oauth2/authorize"
				+ "?appid=" + app.getAppId() + "&redirect_uri=" + Encodes.urlEncode(url) + "&response_type=code"
				+ "&scope=" + "snsapi_userinfo" + "&state=" + state + "&component_appid=" + app.getAppId()
				+ "#wechat_redirect";
		return CompletableFuture.completedFuture(content);
	}

	/**
	 * 第三方平台：换取token
	 *
	 * @param app   app
	 * @param code  code
	 * @param state state
	 * @return 异步结果
	 */
	public CompletableFuture<SnsToken> oauth2AccessToken_component(AuthorizerWechatConfig app, String code,
			String state) {
		if (!(StringUtils.isNotBlank(code) && StringUtils.isNotBlank(state))) {
			return CompletableFuture.completedFuture(null);
		}
		CompletableFuture<SnsToken> future = this.getHttpService().get()
				.setUrl("https://api.weixin.qq.com/sns/oauth2/component/access_token")
				.addQueryParam("appid", app.getAppId()).addQueryParam("code", code)
				.addQueryParam("grant_type", "authorization_code")
				.addQueryParam("component_appid", app.getComponentAppId())
				.addQueryParam("component_access_token", app.getComponentAccessToken()).jsonResult(SnsToken.class)
				.future();
		return future.thenApply(res -> {
			if (res != null) {
				res.setCode(code);
				res.setState(state);
			}
			return res;
		});
	}

	/**
	 * 第三方平台：换取 pre_auth_code
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<PreAuthCode> preAuthCode_component(ComponentConfig app) {
		CompletableFuture<PreAuthCode> future = this.getHttpService().get()
				.setUrl("https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode")
				.addQueryParam("component_access_token", app.getAccessToken())
				.addQueryParam("component_appid", app.getAppId()).jsonResult(PreAuthCode.class).future();
		return future.thenApply(token -> {
			if (token != null) {
				token.setAddTime(System.currentTimeMillis());
			}
			return token;
		});
	}

	/**
	 * 第三方平台：查询授权
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<AuthorizationInfo> apiQueryAuth_component(ComponentConfig app, String authorization_code) {
		CompletableFuture<AuthorizationInfo> future = this.getHttpService().post()
				.setUrl("https://api.weixin.qq.com/cgi-bin/component/api_query_auth")
				.addQueryParam("component_access_token", app.getAccessToken())
				.addQueryParam("component_appid", app.getAppId())
				.addQueryParam("authorization_code", authorization_code).jsonResult(AuthorizationInfo.class).future();
		return future.thenApply(token -> {
			if (token != null) {
				token.setAddTime(System.currentTimeMillis());
			}
			return token;
		});
	}

	/**
	 * 第三方平台：刷新授权token
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<AuthorizerAccessToken> apiAuthorizerToken_component(AuthorizerWechatConfig app) {
		CompletableFuture<AuthorizerAccessToken> future = this.getHttpService().post()
				.setUrl("https://api.weixin.qq.com/cgi-bin/component/api_query_auth")
				.addQueryParam("component_access_token", app.getComponentAccessToken())
				.addQueryParam("component_appid", app.getComponentAppId())
				.addQueryParam("authorizer_appid", app.getAppId())
				.addQueryParam("authorizer_refresh_token", app.getRefreshToken())
				.jsonResult(AuthorizerAccessToken.class).future();
		return future.thenApply(token -> {
			if (token != null) {
				token.setAddTime(System.currentTimeMillis());
			}
			return token;
		});
	}

	/**
	 * 第三方平台：获取授权方的帐号基本信息
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<AuthorizerInfoResult> apiGetAuthorizerInfo_component(AuthorizerWechatConfig app) {
		CompletableFuture<AuthorizerInfoResult> future = this.getHttpService().post()
				.setUrl("https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info")
				.addQueryParam("component_access_token", app.getComponentAccessToken())
				.addQueryParam("component_appid", app.getComponentAppId())
				.addQueryParam("authorizer_appid", app.getAppId()).jsonResult(AuthorizerInfoResult.class).future();
		return future.thenApply(token -> {
			return token;
		});
	}

	/**
	 * 第三方平台：获取授权方选项信息
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<AuthorizerOption> apiGetAuthorizerOption_component(AuthorizerWechatConfig app,
			String option_name) {
		CompletableFuture<AuthorizerOption> future = this.getHttpService().post()
				.setUrl("https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option")
				.addQueryParam("component_access_token", app.getComponentAccessToken())
				.addQueryParam("component_appid", app.getComponentAppId())
				.addQueryParam("authorizer_appid", app.getAppId()).addQueryParam("option_name", option_name)
				.jsonResult(AuthorizerOption.class).future();
		return future.thenApply(token -> {
			return token;
		});
	}

	/**
	 * 第三方平台：获取授权方选项信息
	 *
	 * @param app app
	 * @return 异步结果
	 */
	public CompletableFuture<AuthorizerOption> apiSetAuthorizerOption_component(AuthorizerWechatConfig app,
			String option_name, String option_value) {
		CompletableFuture<AuthorizerOption> future = this.getHttpService().post()
				.setUrl("https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option")
				.addFormParam("component_access_token", app.getComponentAccessToken())
				.addFormParam("component_appid", app.getComponentAppId())
				.addFormParam("authorizer_appid", app.getAppId()).addFormParam("option_name", option_name)
				.addFormParam("option_name", option_name).addFormParam("option_value", option_value)
				.jsonResult(AuthorizerOption.class).future();
		return future.thenApply(token -> {
			return token;
		});
	}
}
